﻿using BacklogParser.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace BacklogParser.Parsers
{
    public static class OfficeSpecificBibDataParser
    {
        public static List<OfficeSpecificBibData> Parse(List<XElement> data)
        {
            var result = new List<OfficeSpecificBibData>();

            foreach(var item in data)
            {
                var appealData = item.Descendants(Constants.Epo + "ep-appeal-data").ToList();
                var revocationProcedure = item.Descendants(Constants.Epo + "ep-revocation-procedure").ToList();
                var petitionReview = item.Descendants(Constants.Epo + "ep-petition-review").ToList();
                var limitationProcedure = item.Descendants(Constants.Epo + "ep-limitation-procedure").ToList();

                var parsed = new OfficeSpecificBibData();

                parsed.AppealData = ApealDataParse(appealData);
                parsed.RevocationProcedure = RevocationProcedureParse(revocationProcedure);
                parsed.PetitionReview = PetitionReviewParse(petitionReview);

                result.Add(parsed);
            }



            return result;
        }

        private static List<EpAppealData> ApealDataParse(List<XElement> elems)
        {
            var result = new List<EpAppealData>();

            foreach(var item in elems)
            {
                var date = item.Descendants(Constants.Epo + "date").FirstOrDefault();
                var statementOfGrounds = item.Descendants(Constants.Epo + "ep-date-statement-of-grounds-filed").FirstOrDefault();
                var interlocutoryRevision = item.Descendants(Constants.Epo + "ep-date-interlocutory-revision").FirstOrDefault();
                var appealResult = item.Descendants(Constants.Epo + "ep-appeal-result").FirstOrDefault();

                var res = new EpAppealData();

                if (date != null)
                    res.Date = date.Value;
                if (statementOfGrounds != null)
                    res.DateStatementsOfGroundsFiled = statementOfGrounds.Value;
                if (interlocutoryRevision != null)
                    res.DateInterlocutoryRevision = interlocutoryRevision.Value;
                if (appealResult != null)
                    res.AppealResult = appealResult.Value;

                result.Add(res);
            }

            return result;
        }

        private static List<EpRevocationProcedure> RevocationProcedureParse(List<XElement> elems)
        {
            var result = new List<EpRevocationProcedure>();

            foreach (var item in elems)
            {
                var revocationDate = item.Descendants(Constants.Epo + "ep-revocation-procedure-date").FirstOrDefault();
                var procedureDecision = item.Descendants(Constants.Epo + "ep-revocation-procedure-decision").FirstOrDefault();
                var procedurePaid = item.Descendants(Constants.Epo + "ep-revocation-procedure-paid").FirstOrDefault();
                var revocationDateDispatch = item.Descendants(Constants.Epo + "ep-revocation-date-dispatch").FirstOrDefault();
                var legalEffect = item.Descendants(Constants.Epo + "ep-revocation-legal-effect").FirstOrDefault();
                
                var res = new EpRevocationProcedure();

                if (revocationDate != null)
                    res.ProcedureDate = revocationDate.Value;

                if (procedureDecision != null)
                    res.ProcedureDecision = procedureDecision.Value;

                if (procedurePaid != null)
                    res.ProcedurePaid = procedurePaid.Value;

                if (revocationDateDispatch != null)
                    res.DateDispatch = revocationDateDispatch.Value;

                if (legalEffect != null)
                    res.LegalEffect = legalEffect.Value;

                result.Add(res);
            }

            return result;
        }

        private static List<EpPetitionReview> PetitionReviewParse(List<XElement> elems)
        {
            var result = new List<EpPetitionReview>();

            foreach (var item in elems)
            {
                var appealNumber = item.Descendants(Constants.Epo + "ep-petition-review-appeal-number").FirstOrDefault();
                var reviewDate = item.Descendants(Constants.Epo + "ep-petition-review-date").FirstOrDefault();
                var petitionerCode = item.Descendants(Constants.Epo + "ep-petition-review-petitioner-code").FirstOrDefault();
                var decisionDate = item.Descendants(Constants.Epo + "ep-petition-review-decision-date").FirstOrDefault();
                var kind = item.Descendants(Constants.Epo + "ep-petition-review-kind").FirstOrDefault();

                var res = new EpPetitionReview();

                if (appealNumber != null)
                    res.ReviewAppealNumber = appealNumber.Value;

                if (reviewDate != null)
                    res.ReviewDate = reviewDate.Value;

                if (petitionerCode != null)
                    res.ReviewPetitionerCode = petitionerCode.Value;

                if (decisionDate != null)
                    res.ReviewDecisionDate = decisionDate.Value;

                if (kind != null)
                    res.ReviewKind = kind.Value;

                result.Add(res);
            }

            return result;
        }

        private static List<EpLimitationProcedure> LimitationProcedureParse(List<XElement> elems)
        {
            var result = new List<EpLimitationProcedure>();

            foreach (var item in elems)
            {
                var res = new EpLimitationProcedure();
                var limitationFiling = item.Descendants(Constants.Epo + "ep-limitation-filing").First();

                var filingDate = limitationFiling.Descendants(Constants.Epo + "ep-limitation-filing-date").FirstOrDefault();
                var filingDecision = limitationFiling.Descendants(Constants.Epo + "ep-limitationfiling-decision").FirstOrDefault();

                if(filingDate != null)
                    res.FilingDate = filingDate.Value;

                if (filingDecision != null)
                    res.FilingDecision = filingDecision.Value;

                var rejection = item.Descendants(Constants.Epo + "ep-limitation-rejection").FirstOrDefault();

                if(rejection != null)
                {
                    var rejectionKind = rejection.Descendants(Constants.Epo + "ep-limitation-rejection-kind").FirstOrDefault();
                    var rejectionDispatchDate = rejection.Descendants(Constants.Epo + "eplimitation-rejection-dispatch-date").FirstOrDefault();
                    var rejectionLegalDate = rejection.Descendants(Constants.Epo + "ep-limitation-rejection-legal-date").FirstOrDefault();

                    if (rejectionKind != null)
                        res.RejectionKind = rejectionKind.Value;

                    if (rejectionLegalDate != null)
                        res.RejectionLegalDate = rejectionLegalDate.Value;

                    if (rejectionDispatchDate != null)
                        res.RejectionDispatchDate = rejectionDispatchDate.Value;
                }


                var allowed = item.Descendants(Constants.Epo + "ep-limitation-allowed").FirstOrDefault();

                if(allowed != null)
                {
                    var allowedDispatchDate = allowed.Descendants(Constants.Epo + "ep-limitation-request-dispatch-date").FirstOrDefault();
                    var allowedRequestPayDate = allowed.Descendants(Constants.Epo + "eplimitation-request-pay-date").FirstOrDefault();

                    if (allowedDispatchDate != null)
                        res.AllowedDispatchDate = allowedDispatchDate.Value;

                    if (allowedRequestPayDate != null)
                        res.AllowedRequestPayDate = allowedRequestPayDate.Value;
                }

                result.Add(res);
            }

            return result;
        }
    }
}
